/**
 * File관련 공통모듈
 * 
 * @author KJH
 * @version 1.0, 2009-07-23 
 * @fix([수정자]) [yyyy-mm-dd]: [수정 내용]
 *
 */

/**
 * 함수 리스트
 * 
 * DataByteBuffer : 생성자
 * append : byte[] 값을 추가한다.(함수 2개)
 * toByte : 저장된 전체 byte[]값을 리턴
 * getLength : 저장된 전체 byte[]의 크기
 * indexOf : 특정문자의 위치 출력
 * subDataByteBuffer : 특정위치의 byte[]데이타 출력(함수 2개)
 * read : 특정위치의 데이타 읽기
 *
 */

package com.ubst.smartad.common;
import java.util.*;

public class DataByteBuffer {

	private Vector bytes_vec;

	public DataByteBuffer() {
		bytes_vec = new Vector();
	}

	/**
	 * byte[]값을 추가한다.
	 * 
	 * @param array_b : 추가할 byte[] 데이타
	 * @return 
	 *
	*/
	public void append(byte[] array_b){
		bytes_vec.addElement(array_b);
	}

	/**
	 * byte[]값을 추가한다.
	 * 
	 * @param array_b : 추가할 byte[] 데이타
	 * @param off : 시작위치
	 * @param len : byte[] 크기
	 * @return 
	 *
	*/
	public void append(byte[] array_b, int off, int len){
		byte[] buf = new byte[len];
		System.arraycopy(array_b, off, buf, 0, len);
		bytes_vec.addElement(buf);
	}

	/**
	 * vector에 저장된 전체 bytep[]값을 리턴한다.
	 * 
	 * @return 전체byte[]값
	 *
	*/
	public byte[] toByte(){

		byte[] result = new byte[getLength()];
		int pos=0;
		int vLen = this.bytes_vec.size();
		for(int i=0; i<vLen; i++){
			byte[] buf = (byte[])bytes_vec.elementAt(i);
			if(buf != null){
				System.arraycopy(buf, 0, result, pos, buf.length);
				pos +=buf.length;
			}
		}
		return result;
	}

	/**
	 * 전체 byte[]의 크기.
	 * 
	 * @param 
	 * @return 전체배열의 크기
	 *
	*/
	public int getLength(){
		int result=0;
		int vLen = this.bytes_vec.size();

		for(int i=0; i<vLen; i++){
			byte[] buf = (byte[])bytes_vec.elementAt(i);
			if(buf != null){
				result +=buf.length;
			}
		}
		return result;
	}

	/**
	 * 특정 문자의 위치 출력
	 * 
	 * @param str : 찾고자하는 내용
	 * @return 찾은위치(없을 경우 -1)
	 *
	*/
	public int indexOf(String str){
		byte[] src = this.toByte();
		byte[] searchBuf = str.getBytes();

		if(src.length < searchBuf.length){
			return -1;
		}

		int idx = -1;
		byte[] dest = new byte[searchBuf.length];
		for(int i=0; i<src.length; i++){
			if(src.length-i < dest.length){
				break;
			}
			System.arraycopy(src, i, dest, 0, dest.length);
			boolean bingo = true;
			for(int j=0; j<dest.length; j++){
				if(dest[j] != searchBuf[j]){
					bingo=false;
					break;
				}
			}
			if(bingo){
				idx = i;
				break;
			}
		} // end for
		return idx;
	}

	/**
	 * 특정위치의 byte[] 출력
	 * 
	 * @param off : 출력하고자하는 시작위치
	 * @return 특정위치부터의 byte[]값
	 *
	*/
	public DataByteBuffer subDataByteBuffer(int off) throws Exception{
		byte[] buf = this.toByte();
		int len = (buf.length-off);
		byte[] destBuf = new byte[len];

		System.arraycopy(buf, off, destBuf, 0, len);

		DataByteBuffer result = new DataByteBuffer();
		result.append(destBuf);

		return result;
	}

	/**
	 * 특정위치의 byte[] 출력
	 * 
	 * @param start : 출력하고자하는 시작위치
	 * @param end : 출력하고자하는 종료위치
	 * @return 특정위치부터의 byte[]값
	 *
	*/
	public DataByteBuffer subDataByteBuffer(int start, int end) throws Exception{
		int len = end-start;

		byte[] buf = this.toByte();
		byte[] destBuf = new byte[len];

		System.arraycopy(buf, start, destBuf, 0, len);

		DataByteBuffer result = new DataByteBuffer();
		result.append(destBuf);

		return result;
	}

	/**
	 * 특정위치의 byte[]데이타 읽기
	 * 
	 * @param buf : 데이타를 출력할 byte[]
	 * @param off : 읽을 시작위치
	 * @param len : 읽을 크기
	 * @return 읽은 데이타 크기
	 *
	*/
	public int read(byte[] buf, int off, int len) throws Exception{
		int readLen = 0;

		byte[] src = this.toByte();
		if((src.length-off) < len){
			readLen=src.length-off;
		}else{
			readLen = len;
		}
		System.arraycopy(src, off, buf, 0, readLen);
		return readLen;
	}

}
